💡 Web projects can be hard. Our solutions specialists can help!

How the Facebook content placeholder works

By George Phillips · 15 Nov 2014
How the Facebook content placeholder works

This is the first post of my new blog series called Deconstructions. Showcasing cool things people are doing in web development and breaking them down step by step. My first target is a cool content placeholder from the most recent Facebook overhaul. Before your friend's latest selfie or dog picture loads you may have noticed this nice bit of polish.

What is it?

Straight to the point here it is. Below you can see my clone and my HTML (I changed a few things to make it easier to see):

<div class="timeline-wrapper">
<div class="timeline-item">
<div class="animated-background">
<div class="background-masker header-top"></div>
<div class="background-masker header-left"></div>
<div class="background-masker header-right"></div>
<div class="background-masker header-bottom"></div>
<div class="background-masker subheader-left"></div>
<div class="background-masker subheader-right"></div>
<div class="background-masker subheader-bottom"></div>
<div class="background-masker content-top"></div>
<div class="background-masker content-first-end"></div>
<div class="background-masker content-second-line"></div>
<div class="background-masker content-second-end"></div>
<div class="background-masker content-third-line"></div>
<div class="background-masker content-third-end"></div>
</div>
</div>
</div>

As you can see the demo only contains three types on elements:

A Wrapper

This is the easiest bit, it's just a centered div to wrap the content. I chose to use the same colours as Facebook.

.timeline-item {
background: #fff;
border: 1px solid;
border-color: #e5e6e9 #dfe0e4 #d0d1d5;
border-radius: 3px;
padding: 12px;

margin: 0 auto;
max-width: 472px;
min-height: 200px;
}

A Fancy Animated Background

This is where the magic happens. It's a box that is has a animated background and that background happens to be a CSS gradient.

@keyframes placeHolderShimmer{
0%{
background-position: -468px 0
}
100%{
background-position: 468px 0
}
}

.animated-background {
animation-duration: 1s;
animation-fill-mode: forwards;
animation-iteration-count: infinite;
animation-name: placeHolderShimmer;
animation-timing-function: linear;
background: #f6f7f8;
background: linear-gradient(to right, #eeeeee 8%, #dddddd 18%, #eeeeee 33%);
background-size: 800px 104px;
height: 96px;
position: relative;
}

Plenty of Tiny Masking Blocks

Without these the previous step just looks like a stupidly large progress bar. This gives the shape to the placeholder. It's just lots of little white divs that sit on top so you can't see the animation. This part gets messy fast. I have added some borders to this version to illustrate where the masks are placed (Try hovering on each block).

.background-masker {
background: #fff;
position: absolute;
}

/* Every thing below this is just positioning */

.background-masker.header-top,
.background-masker.header-bottom,
.background-masker.subheader-bottom
{
top: 0;
left: 40px;
right: 0;
height: 10px;
}

.background-masker.header-left,
.background-masker.subheader-left,
.background-masker.header-right,
.background-masker.subheader-right
{
top: 10px;
left: 40px;
height: 8px;
width: 10px;
}

.background-masker.header-bottom {
top: 18px;
height: 6px;
}

.background-masker.subheader-left,
.background-masker.subheader-right
{
top: 24px;
height: 6px;
}

.background-masker.header-right,
.background-masker.subheader-right
{
width: auto;
left: 300px;
right: 0;
}

.background-masker.subheader-right {
left: 230px;
}

.background-masker.subheader-bottom {
top: 30px;
height: 10px;
}

.background-masker.content-top,
.background-masker.content-second-line,
.background-masker.content-third-line,
.background-masker.content-second-end,
.background-masker.content-third-end,
.background-masker.content-first-end
{
top: 40px;
left: 0;
right: 0;
height: 6px;
}

.background-masker.content-top {
height:20px;
}

.background-masker.content-first-end,
.background-masker.content-second-end,
.background-masker.content-third-end
{
width: auto;
left: 380px;
right: 0;
top: 60px;
height: 8px;
}

.background-masker.content-second-line {
top: 68px;
}

.background-masker.content-second-end {
left: 420px;
top: 74px;
}

.background-masker.content-third-line {
top: 82px;
}

.background-masker.content-third-end {
left: 300px;
top: 88px;
}

Why would I ever use this?

We can't always remove having to wait for information but we can make the wait feel shorter. By giving some indication of what is going on and giving visual stimulus the user feels immediately more comfortable and less likely to leave. This is exactly like putting a progress bar on a long action. Apart from the fact it's some fancy polish, it's great usability. I think this feature is better than your average loading symbol because it actually feels like the content is almost there. After a quick search I found this article which explains it quite well.

That's it

I have been looking for a situation I can use a loader like this but sadly one has not come up yet. I may use it for the upcoming GitHub integration while I am loading the list of repositories. If you found this useful or have any questions feel free to comment below. I am going to try to do one of these a week so if you see something you want deconstructed let me know.

Note: I used unprefixed CSS in the code examples to keep it clean. You can use Our CSS Prefixer to get cross a cross browser version.

Launch your website today

Give your content team full autonomy on your developer-approved tech stack with CloudCannon.

Get started free!

You might also like:

Designing components for your website editors: a CloudCannon case study

Designing components for your website editors: a CloudCannon case study

Victoria Roberts Â· 28 Oct 2024

The eternal balancing act: load time vs. delay time

The eternal balancing act: load time vs. delay time

David Large · Adon Moskal
16 Oct 2024

What is a headless CMS?

What is a headless CMS?

CloudCannon Â· 27 Sep 2024